import asyncio
import os
import tempfile
from typing import Dict, Any, Optional, List
from urllib.parse import urlparse, parse_qs
import yt_dlp
from datetime import datetime

from config.logging_config import ProjectLoggers
from utils.qiniu_helper import QiniuHelper
from utils.file_helper import FileHelper

logger = ProjectLoggers.get_service_logger()

class YouTubeDownloaderService:
    """YouTube视频下载服务"""
    
    def __init__(self):
        self.temp_dir = tempfile.gettempdir()
        # 配置cookies文件路径（用于获取高质量视频）
        self.cookies_file = os.path.join(os.getcwd(), "youtube_cookies.txt")
        
        # 尝试从浏览器获取cookies的路径（可选）
        self.cookie_sources = [
            # Chrome cookies
            "chrome",
            # Firefox cookies  
            "firefox",
            # Safari cookies
            "safari",
            # Edge cookies
            "edge"
        ]
        
    def _get_video_id_from_url(self, url: str) -> Optional[str]:
        """从YouTube URL中提取视频ID"""
        try:
            parsed_url = urlparse(url)
            
            # 处理不同类型的YouTube URL
            if 'youtube.com' in parsed_url.netloc:
                if '/watch' in parsed_url.path:
                    # 标准YouTube视频: https://www.youtube.com/watch?v=VIDEO_ID
                    query_params = parse_qs(parsed_url.query)
                    return query_params.get('v', [None])[0]
                elif '/shorts/' in parsed_url.path:
                    # YouTube Shorts: https://youtube.com/shorts/VIDEO_ID
                    return parsed_url.path.split('/shorts/')[-1].split('?')[0]
                elif '/embed/' in parsed_url.path:
                    # 嵌入式视频: https://www.youtube.com/embed/VIDEO_ID
                    return parsed_url.path.split('/embed/')[-1].split('?')[0]
            elif 'youtu.be' in parsed_url.netloc:
                # 短链接: https://youtu.be/VIDEO_ID
                return parsed_url.path.lstrip('/')
                
            return None
        except Exception as e:
            logger.error(f"解析YouTube URL失败: {str(e)}")
            return None
    
    def _get_manual_cookie_path(self) -> Optional[str]:
        """检查是否存在手动cookie文件"""
        import os
        cookie_paths = [
            os.path.join(self.temp_dir, "youtube_cookies.txt"),
            os.path.join(os.getcwd(), "youtube_cookies.txt"),
            os.path.join(os.path.expanduser("~"), "youtube_cookies.txt"),
        ]
        
        for path in cookie_paths:
            if os.path.exists(path):
                logger.info(f"找到手动cookie文件: {path}")
                return path
        return None
    
    def _check_cookies(self) -> bool:
        """检查cookies文件是否存在"""
        return os.path.exists(self.cookies_file)
    
    def _get_base_ydl_opts(self, bypass_bot_detection: bool = False) -> Dict[str, Any]:
        """获取基础的yt-dlp配置选项"""
        opts = {
            'quiet': True,
            'no_warnings': True,
            'extractaudio': False,
            # 优化的用户代理和请求头，提高无cookies情况下的成功率
            'http_headers': {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                'Accept-Language': 'en-us,en;q=0.5',
                'Accept-Encoding': 'gzip,deflate',
                'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
                'Keep-Alive': '300',
                'Connection': 'keep-alive',
            },
            # 添加额外选项来提高无cookies情况下的成功率
            'no_color': True,
            'prefer_free_formats': True,
            'youtube_include_dash_manifest': False,
        }
        
        # 如果需要绕过机器人检测，添加更多选项
        if bypass_bot_detection:
            opts.update({
                'extractor_args': {
                    'youtube': {
                        'skip': ['dash', 'hls'],
                        'player_client': ['android', 'web'],
                        'player_skip': ['configs'],
                    }
                },
                'sleep_interval': 1,
                'max_sleep_interval': 3,
                'sleep_interval_requests': 1,
            })
        
        # 优先使用浏览器cookies，这是最有效的方法
        try:
            opts['cookiesfrombrowser'] = ('chrome',)
            logger.info("使用Chrome浏览器cookies获取高质量视频")
        except:
            # 如果浏览器cookies失败，回退到cookies文件
            if self._check_cookies():
                opts['cookiefile'] = self.cookies_file
                logger.info("回退到cookies文件获取视频")
            else:
                logger.info("无可用cookies，使用基础配置")
        
        return opts
    
    async def _try_multiple_extraction_methods(self, youtube_url: str, format_selector: str = "best") -> Dict[str, Any]:
        """尝试多种提取方法来绕过YouTube的反机器人检测"""
        extraction_methods = [
            {
                "name": "标准方法",
                "opts": self._get_base_ydl_opts(bypass_bot_detection=True)
            },
            {
                "name": "Android客户端模拟",
                "opts": {
                    **self._get_base_ydl_opts(),
                    'extractor_args': {
                        'youtube': {
                            'player_client': ['android'],
                        }
                    }
                }
            },
            {
                "name": "iOS客户端模拟", 
                "opts": {
                    **self._get_base_ydl_opts(),
                    'extractor_args': {
                        'youtube': {
                            'player_client': ['ios'],
                        }
                    }
                }
            },
            {
                "name": "Web客户端（无cookies）",
                "opts": {
                    'quiet': True,
                    'no_warnings': True,
                    'extractaudio': False,
                    'http_headers': {
                        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
                    },
                }
            }
        ]
        
        last_error = None
        
        for method in extraction_methods:
            try:
                logger.info(f"🔄 尝试提取方法: {method['name']}")
                
                opts = method['opts'].copy()
                opts['format'] = format_selector
                
                def _extract():
                    with yt_dlp.YoutubeDL(opts) as ydl:
                        return ydl.extract_info(youtube_url, download=False)
                
                loop = asyncio.get_event_loop()
                info = await loop.run_in_executor(None, _extract)
                
                if info:
                    logger.info(f"✅ 成功使用方法: {method['name']}")
                    return {
                        "success": True,
                        "data": info,
                        "method_used": method['name']
                    }
                    
            except Exception as e:
                error_msg = str(e)
                last_error = error_msg
                logger.warning(f"❌ 方法 '{method['name']}' 失败: {error_msg}")
                
                # 如果是机器人检测错误，继续尝试下一个方法
                if "Sign in to confirm" in error_msg or "bot" in error_msg.lower():
                    continue
                # 如果是其他错误，可能视频本身有问题
                elif "Video unavailable" in error_msg or "Private video" in error_msg:
                    break
        
        return {
            "success": False,
            "error": f"所有提取方法都失败了，最后错误: {last_error}"
        }
    
    def _is_youtube_url(self, url: str) -> bool:
        """检查是否为有效的YouTube URL"""
        return self._get_video_id_from_url(url) is not None
    
    async def get_video_info(self, youtube_url: str) -> Dict[str, Any]:
        """获取YouTube视频信息"""
        try:
            if not self._is_youtube_url(youtube_url):
                return {
                    "success": False,
                    "error": "不是有效的YouTube链接"
                }
            
            # 使用多重提取方法来绕过YouTube的反机器人检测
            extraction_result = await self._try_multiple_extraction_methods(
                youtube_url, 
                'best[height<=1080]/best'
            )
            
            if not extraction_result["success"]:
                return {
                    "success": False,
                    "error": extraction_result["error"]
                }
            
            info = extraction_result["data"]
            method_used = extraction_result["method_used"]
            
            if not info:
                return {
                    "success": False,
                    "error": "无法获取视频信息"
                }
            
            # 提取有用的信息
            video_info = {
                "video_id": info.get('id'),
                "title": info.get('title'),
                "uploader": info.get('uploader'),
                "duration": info.get('duration'),
                "view_count": info.get('view_count'),
                "upload_date": info.get('upload_date'),
                "description": info.get('description', '')[:200] + '...' if info.get('description', '') else '',
                "thumbnail": info.get('thumbnail'),
                "formats": [],
                "extraction_method": method_used  # 记录成功的提取方法
            }
            
            # 获取可用格式
            formats = info.get('formats', [])
            for fmt in formats:
                if fmt.get('vcodec') != 'none':  # 只要包含视频的格式
                    format_info = {
                        "format_id": fmt.get('format_id'),
                        "ext": fmt.get('ext'),
                        "resolution": fmt.get('resolution') or f"{fmt.get('width', 'unknown')}x{fmt.get('height', 'unknown')}",
                        "filesize": fmt.get('filesize'),
                        "filesize_approx": fmt.get('filesize_approx'),
                        "url": fmt.get('url'),
                        "quality": fmt.get('quality'),
                        "format_note": fmt.get('format_note')
                    }
                    video_info["formats"].append(format_info)
            
            # 按质量排序，支持1080p高质量格式
            video_info["formats"] = sorted(
                video_info["formats"], 
                key=lambda x: (x.get('quality') or 0), 
                reverse=True
            )
            
            logger.info(f"成功获取YouTube视频信息: {video_info['title']}")
            
            return {
                "success": True,
                "data": video_info
            }
            
        except Exception as e:
            logger.error(f"获取YouTube视频信息失败: {str(e)}")
            return {
                "success": False,
                "error": f"获取视频信息失败: {str(e)}"
            }
    
    async def get_download_urls(self, youtube_url: str, quality: str = "720p") -> Dict[str, Any]:
        """获取YouTube视频下载链接"""
        try:
            if not self._is_youtube_url(youtube_url):
                return {
                    "success": False,
                    "error": "不是有效的YouTube链接"
                }
            
            # 根据质量设置格式选择器 - 优化为支持1080p，使用更简洁的格式
            quality_map = {
                "1080p": "bestvideo[height<=1080]+bestaudio/best[height<=1080]",
                "1080p60": "bestvideo[height<=1080][fps>=60]+bestaudio/best[height<=1080][fps>=60]",
                "720p": "bestvideo[height<=720]+bestaudio/best[height<=720]",
                "720p60": "bestvideo[height<=720][fps>=60]+bestaudio/best[height<=720][fps>=60]",
                "480p": "bestvideo[height<=480]+bestaudio/best[height<=480]",
                "360p": "bestvideo[height<=360]+bestaudio/best[height<=360]",
                "best": "bestvideo+bestaudio/best",
                "worst": "worstvideo+bestaudio/worst"
            }
            
            format_selector = quality_map.get(quality, "bestvideo[height<=720]+bestaudio/best[height<=720]")
            
            # 使用基础配置并添加格式选择器
            ydl_opts = self._get_base_ydl_opts(bypass_bot_detection=True)
            ydl_opts['format'] = format_selector
            
            def _extract_info():
                with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                    return ydl.extract_info(youtube_url, download=False)
            
            loop = asyncio.get_event_loop()
            info = await loop.run_in_executor(None, _extract_info)
            
            if not info:
                return {
                    "success": False,
                    "error": "无法获取下载链接"
                }
            
            # 获取最佳格式的下载链接
            download_url = info.get('url')
            if not download_url:
                return {
                    "success": False,
                    "error": "无法获取有效的下载链接"
                }
            
            result = {
                "video_id": info.get('id'),
                "title": info.get('title'),
                "download_url": download_url,
                "format": info.get('ext'),
                "resolution": info.get('resolution') or f"{info.get('width', 'unknown')}x{info.get('height', 'unknown')}",
                "filesize": info.get('filesize'),
                "filesize_approx": info.get('filesize_approx'),
                "duration": info.get('duration'),
                "thumbnail": info.get('thumbnail')
            }
            
            logger.info(f"成功获取YouTube视频下载链接: {result['title']}")
            
            return {
                "success": True,
                "data": result
            }
            
        except Exception as e:
            logger.error(f"获取YouTube下载链接失败: {str(e)}")
            return {
                "success": False,
                "error": f"获取下载链接失败: {str(e)}"
            }
    
    async def get_1080p_download_urls(self, youtube_url: str) -> Dict[str, Any]:
        """
        专门获取1080p视频下载链接的优化方法
        使用多种策略尝试获取高质量视频
        """
        try:
            if not self._is_youtube_url(youtube_url):
                return {
                    "success": False,
                    "error": "不是有效的YouTube链接"
                }
            
            # 策略1: 尝试直接获取1080p
            strategies = [
                {
                    "name": "1080p直接获取",
                    "format": "bestvideo[height<=1080][ext=mp4]+bestaudio[ext=m4a]/best[height<=1080][ext=mp4]"
                },
                {
                    "name": "1080p分离流",
                    "format": "bestvideo[height<=1080]+bestaudio/best[height<=1080]"
                },
                {
                    "name": "最佳可用质量",
                    "format": "bestvideo[height<=1080]/best"
                },
                {
                    "name": "通用最佳",
                    "format": "best"
                }
            ]
            
            last_error = None
            
            for strategy in strategies:
                try:
                    logger.info(f"尝试策略: {strategy['name']}")
                    
                    # 使用多重提取方法
                    extraction_result = await self._try_multiple_extraction_methods(
                        youtube_url, 
                        strategy['format']
                    )
                    
                    if extraction_result["success"]:
                        info = extraction_result["data"]
                        method_used = extraction_result["method_used"]
                        
                        if info and info.get('url'):
                            # 成功获取链接
                            result_data = {
                                "video_id": info.get('id'),
                                "title": info.get('title'),
                                "download_url": info.get('url'),
                                "format": info.get('ext', 'mp4'),
                                "resolution": f"{info.get('width', 'unknown')}x{info.get('height', 'unknown')}",
                                "filesize": info.get('filesize') or info.get('filesize_approx'),
                                "duration": info.get('duration'),
                                "strategy_used": strategy['name'],
                                "extraction_method": method_used,
                                "quality_achieved": f"{info.get('height', 'unknown')}p",
                                "fps": info.get('fps'),
                                "vcodec": info.get('vcodec'),
                                "acodec": info.get('acodec')
                            }
                            
                            logger.info(f"✅ 成功使用策略 '{strategy['name']}' + 方法 '{method_used}' 获取视频: {result_data['quality_achieved']}")
                            
                            return {
                                "success": True,
                                "data": result_data
                            }
                    else:
                        last_error = extraction_result["error"]
                        logger.warning(f"策略 '{strategy['name']}' 失败: {last_error}")
                        continue
                
                except Exception as e:
                    last_error = str(e)
                    logger.warning(f"策略 '{strategy['name']}' 失败: {str(e)}")
                    continue
            
            # 所有策略都失败了
            return {
                "success": False,
                "error": f"所有获取策略都失败了，最后错误: {last_error}"
            }
            
        except Exception as e:
            logger.error(f"获取1080p视频链接失败: {str(e)}")
            return {
                "success": False,
                "error": f"获取1080p视频链接失败: {str(e)}"
            }
    
    async def download_video(self, youtube_url: str, quality: str = "720p", upload_to_qiniu: bool = True) -> Dict[str, Any]:
        """下载YouTube视频"""
        try:
            if not self._is_youtube_url(youtube_url):
                return {
                    "success": False,
                    "error": "不是有效的YouTube链接"
                }
            
            # 首先获取视频信息
            info_result = await self.get_video_info(youtube_url)
            if not info_result["success"]:
                return info_result
            
            video_info = info_result["data"]
            safe_title = FileHelper.get_safe_filename(video_info["title"])
            
            # 根据质量设置格式选择器 - 使用改进的格式
            quality_map = {
                "1080p": "bestvideo[height<=1080]+bestaudio/best[height<=1080]",
                "1080p60": "bestvideo[height<=1080][fps>=60]+bestaudio/best[height<=1080][fps>=60]",
                "720p": "bestvideo[height<=720]+bestaudio/best[height<=720]",
                "720p60": "bestvideo[height<=720][fps>=60]+bestaudio/best[height<=720][fps>=60]",
                "480p": "bestvideo[height<=480]+bestaudio/best[height<=480]",
                "360p": "bestvideo[height<=360]+bestaudio/best[height<=360]",
                "best": "bestvideo+bestaudio/best",
                "worst": "worstvideo+bestaudio/worst"
            }
            
            format_selector = quality_map.get(quality, "bestvideo[height<=720]+bestaudio/best[height<=720]")
            
            # 设置下载路径
            output_filename = f"{safe_title}.%(ext)s"
            output_path = os.path.join(self.temp_dir, output_filename)
            
            # 使用基础配置并添加下载特定设置
            ydl_opts = self._get_base_ydl_opts()
            ydl_opts.update({
                'outtmpl': output_path,
                'format': format_selector,
            })
            
            def _download():
                with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                    ydl.download([youtube_url])
                    # 查找实际下载的文件
                    for file in os.listdir(self.temp_dir):
                        if file.startswith(safe_title) and not file.endswith('.part'):
                            return os.path.join(self.temp_dir, file)
                    return None
            
            loop = asyncio.get_event_loop()
            downloaded_file = await loop.run_in_executor(None, _download)
            
            if not downloaded_file or not os.path.exists(downloaded_file):
                return {
                    "success": False,
                    "error": "视频下载失败"
                }
            
            file_size = os.path.getsize(downloaded_file)
            file_ext = os.path.splitext(downloaded_file)[1]
            
            result = {
                "video_id": video_info["video_id"],
                "title": video_info["title"],
                "local_path": downloaded_file,
                "filename": os.path.basename(downloaded_file),
                "file_size": file_size,
                "file_size_display": FileHelper.format_file_size(file_size),
                "format": file_ext.lstrip('.'),
                "duration": video_info["duration"]
            }
            
            # 如果需要上传到七牛云
            if upload_to_qiniu:
                try:
                    # 生成七牛云存储路径
                    qiniu_key = f"youtube/{datetime.now().strftime('%Y%m%d')}/{os.path.basename(downloaded_file)}"
                    
                    # 上传到七牛云
                    upload_result = QiniuHelper.upload_file_by_path(downloaded_file, qiniu_key)
                    
                    if upload_result['success']:
                        result["qiniu_url"] = upload_result['url']
                        result["qiniu_key"] = qiniu_key
                        logger.info(f"视频已上传到七牛云: {upload_result['url']}")
                    else:
                        logger.warning(f"上传到七牛云失败: {upload_result['error']}")
                        result["qiniu_error"] = upload_result['error']
                        
                except Exception as e:
                    logger.warning(f"上传到七牛云时出错: {str(e)}")
                    result["qiniu_error"] = str(e)
                finally:
                    # 清理本地文件
                    try:
                        os.remove(downloaded_file)
                    except:
                        pass
            
            logger.info(f"成功下载YouTube视频: {result['title']}")
            
            return {
                "success": True,
                "data": result
            }
            
        except Exception as e:
            logger.error(f"下载YouTube视频失败: {str(e)}")
            return {
                "success": False,
                "error": f"下载视频失败: {str(e)}"
            }

    async def get_download_urls_with_audio_fallback(self, youtube_url: str, quality: str = "720p") -> Dict[str, Any]:
        """获取YouTube视频下载链接 - 音频回退策略（高清优先）"""
        try:
            if not self._is_youtube_url(youtube_url):
                return {
                    "success": False,
                    "error": "不是有效的YouTube链接"
                }
            
            # 高清优先的音频回退策略
            quality_strategies = {
                "1080p": [
                    # 最佳：1080p H.264 + AAC音频
                    "137+140",
                    "bestvideo[height>=1080][vcodec^=avc1]+bestaudio[acodec^=mp4a]",
                    # 音频回退：1080p视频 + 任何音频
                    "bestvideo[height>=1080][vcodec!^=av01]+bestaudio",
                    # 单独视频回退：1080p无音频
                    "bestvideo[height>=1080][vcodec!^=av01]",
                    # 合并格式回退
                    "best[height>=1080][vcodec!^=av01]"
                ],
                "720p": [
                    # 最佳：720p H.264 + AAC音频  
                    "136+140",
                    "bestvideo[height>=720][vcodec^=avc1]+bestaudio[acodec^=mp4a]",
                    # 音频回退：720p视频 + 任何音频
                    "bestvideo[height>=720][vcodec!^=av01]+bestaudio",
                    # 单独视频回退：720p无音频
                    "bestvideo[height>=720][vcodec!^=av01]",
                    # 合并格式回退
                    "best[height>=720][vcodec!^=av01]"
                ],
                "best": [
                    "137+140/136+140/22",
                    "bestvideo[height>=720][vcodec^=avc1]+bestaudio[acodec^=mp4a]",
                    "bestvideo[vcodec!^=av01]+bestaudio",
                    "bestvideo[vcodec!^=av01]",
                    "best[vcodec!^=av01]"
                ]
            }
            
            format_list = quality_strategies.get(quality, quality_strategies["720p"])
            
            # 检查手动cookie文件
            manual_cookie_path = self._get_manual_cookie_path()
            
            # Cookie获取策略
            cookie_strategies = []
            
            # 手动cookie优先
            if manual_cookie_path:
                cookie_strategies.append({
                    "name": "手动Cookie文件",
                    "opts": {
                        'cookiefile': manual_cookie_path,
                        'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
                    }
                })
            
            # 浏览器自动cookie
            cookie_strategies.extend([
                {
                    "name": "Chrome自动Cookie",
                    "opts": {
                        'cookiesfrombrowser': ('chrome',),
                        'user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
                    }
                },
                {
                    "name": "Safari自动Cookie", 
                    "opts": {
                        'cookiesfrombrowser': ('safari',),
                        'user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15'
                    }
                }
            ])
            
            logger.info(f"音频回退策略：尝试{len(format_list)}种格式 × {len(cookie_strategies)}种Cookie = {len(format_list) * len(cookie_strategies)}种组合")
            
            # 尝试每种组合
            for i, fmt in enumerate(format_list):
                for j, cookie_strategy in enumerate(cookie_strategies):
                    try:
                        strategy_name = f"{cookie_strategy['name']}-{fmt}"
                        logger.info(f"尝试格式 {i+1}/{len(format_list)}, Cookie {j+1}/{len(cookie_strategies)}: {strategy_name}")
                        
                        # 合并配置
                        opts = {
                            'quiet': True,
                            'no_warnings': True,
                            'format': fmt,
                            'prefer_free_formats': False,  # 强制高质量
                            'retries': 2,
                            **cookie_strategy['opts']
                        }
                        
                        def _extract_info():
                            with yt_dlp.YoutubeDL(opts) as ydl:
                                return ydl.extract_info(youtube_url, download=False)
                        
                        loop = asyncio.get_event_loop()
                        info = await loop.run_in_executor(None, _extract_info)
                        
                        if info and info.get('url'):
                            # 验证质量
                            height = info.get('height', 0)
                            width = info.get('width', 0)
                            has_audio = info.get('acodec') != 'none'
                            vcodec = info.get('vcodec', 'unknown')
                            acodec = info.get('acodec', 'none')
                            filesize = info.get('filesize_approx', info.get('filesize', 0))
                            
                            # 检查是否达到质量要求
                            quality_met = True
                            if quality == "1080p" and height < 1080:
                                quality_met = False
                            elif quality == "720p" and height < 720:
                                quality_met = False
                            
                            result = {
                                "video_id": info.get('id'),
                                "title": info.get('title'),
                                "download_url": info.get('url'),
                                "format": info.get('ext'),
                                "resolution": info.get('resolution') or f"{width}x{height}",
                                "width": width,
                                "height": height,
                                "filesize": info.get('filesize'),
                                "filesize_approx": filesize,
                                "duration": info.get('duration'),
                                "thumbnail": info.get('thumbnail'),
                                "strategy_used": strategy_name,
                                "format_id": info.get('format_id'),
                                "acodec": acodec,
                                "vcodec": vcodec,
                                "has_audio": has_audio,
                                "audio_fallback_used": not has_audio,
                                "yt_dlp_version": "2025.6.30",
                                "is_hd": height >= 720,
                                "is_full_hd": height >= 1080,
                                "quality_met": quality_met,
                                "fps": info.get('fps'),
                                "tbr": info.get('tbr')
                            }
                            
                            # 如果质量不足，记录但继续尝试更好的格式
                            if not quality_met:
                                logger.warning(f"格式 {fmt} 获取到 {height}p，低于要求的{quality}，继续尝试")
                                # 存储这个结果作为备用
                                if not hasattr(self, '_fallback_result'):
                                    self._fallback_result = {
                                        "success": True,
                                        "data": result
                                    }
                                continue
                            
                            # 质量满足要求
                            audio_status = "🔊 有音频" if has_audio else "🔇 无音频(仅视频)"
                            logger.info(f"✅ 音频回退策略成功! {strategy_name}")
                            logger.info(f"📺 分辨率: {width}x{height} ({height}p)")
                            logger.info(f"🎬 编解码器: {vcodec} / {acodec}")
                            logger.info(f"🔊 音频状态: {audio_status}")
                            logger.info(f"📦 文件大小: {filesize/1024/1024:.1f}MB" if filesize else "文件大小: 未知")
                            
                            return {
                                "success": True,
                                "data": result
                            }
                            
                    except Exception as e:
                        error_msg = str(e)
                        if "Sign in to confirm you're not a bot" in error_msg:
                            logger.debug(f"策略 {strategy_name} 遇到机器人检测")
                        elif "format is not available" in error_msg.lower():
                            logger.debug(f"策略 {strategy_name} 格式不可用")
                        else:
                            logger.debug(f"策略 {strategy_name} 失败: {error_msg[:50]}...")
                        continue
            
            # 如果有备用结果（质量不足但可用），返回它
            if hasattr(self, '_fallback_result'):
                fallback = self._fallback_result
                delattr(self, '_fallback_result')
                fallback["data"]["warning"] = f"获取到{fallback['data']['height']}p视频，低于请求的{quality}质量"
                logger.warning(f"⚠️  使用备用结果: {fallback['data']['height']}p (请求: {quality})")
                return fallback
            
            # 所有策略都失败
            return {
                "success": False,
                "error": f"音频回退策略失败：无法获取{quality}视频。尝试了{len(format_list) * len(cookie_strategies)}种组合都失败。",
                "yt_dlp_version": "2025.6.30",
                "strategies_tried": len(format_list) * len(cookie_strategies),
                "requested_quality": quality
            }
            
        except Exception as e:
            logger.error(f"音频回退YouTube下载链接获取失败: {str(e)}")
            return {
                "success": False,
                "error": f"音频回退下载链接获取失败: {str(e)}",
                "yt_dlp_version": "2025.6.30"
            }

    async def get_download_urls_advanced(self, youtube_url: str, quality: str = "720p") -> Dict[str, Any]:
        """获取YouTube视频下载链接 - 高级模式（强制高清优先）"""
        try:
            if not self._is_youtube_url(youtube_url):
                return {
                    "success": False,
                    "error": "不是有效的YouTube链接"
                }
            
            # 强制高清格式选择策略 - 根据用户要求优化
            quality_format_map = {
                "1080p": [
                    # 优先：137(1080p H.264) + 140(AAC音频)
                    "137+140",
                    # 备用：1080p H.264视频 + 最佳音频
                    "bestvideo[height>=1080][vcodec^=avc1]+bestaudio[acodec^=mp4a]",
                    # 兜底：任何1080p + 音频
                    "bestvideo[height>=1080][vcodec!^=av01]+bestaudio",
                    # 最后：1080p合并格式
                    "best[height>=1080][vcodec!^=av01]"
                ],
                "1080p60": [
                    # 1080p60 H.264 + AAC
                    "298+140/299+140", 
                    "bestvideo[height>=1080][fps>=60][vcodec^=avc1]+bestaudio[acodec^=mp4a]",
                    "bestvideo[height>=1080][fps>=60][vcodec!^=av01]+bestaudio",
                    "best[height>=1080][fps>=60][vcodec!^=av01]"
                ],
                "720p": [
                    # 720p H.264 + AAC
                    "136+140/22",
                    "bestvideo[height>=720][vcodec^=avc1]+bestaudio[acodec^=mp4a]", 
                    "bestvideo[height>=720][vcodec!^=av01]+bestaudio",
                    "best[height>=720][vcodec!^=av01]"
                ],
                "720p60": [
                    "298+140",
                    "bestvideo[height>=720][fps>=60][vcodec^=avc1]+bestaudio[acodec^=mp4a]",
                    "bestvideo[height>=720][fps>=60][vcodec!^=av01]+bestaudio",
                    "best[height>=720][fps>=60][vcodec!^=av01]"
                ],
                "best": [
                    "137+140/136+140/22",
                    "bestvideo[height>=1080][vcodec^=avc1]+bestaudio[acodec^=mp4a]",
                    "bestvideo[height>=720][vcodec!^=av01]+bestaudio",
                    "best[vcodec!^=av01]"
                ]
            }
            
            format_options = quality_format_map.get(quality, quality_format_map["720p"])
            
            # 检查是否有手动cookie文件
            manual_cookie_path = self._get_manual_cookie_path()
            
            # 高清优先策略配置
            strategies = []
            
            # 如果有手动cookie文件，优先使用
            if manual_cookie_path:
                for fmt in format_options:
                    strategies.append({
                        "name": f"手动Cookie文件策略-{fmt}",
                        "opts": {
                            'quiet': False,  # 开启调试输出
                            'no_warnings': False,
                            'format': fmt,
                            'cookiefile': manual_cookie_path,
                            'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
                            'prefer_free_formats': False,  # 强制高质量
                            'retries': 3,  # 重试3次
                            'quality': quality,
                        }
                    })
            
            # Chrome浏览器自动Cookie策略（多格式尝试）
            for fmt in format_options:
                strategies.append({
                    "name": f"Chrome自动Cookie-{fmt}",
                    "opts": {
                        'quiet': False,  # 开启调试输出
                        'no_warnings': False,
                        'format': fmt,
                        'cookiesfrombrowser': ('chrome',),
                        'user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
                        'prefer_free_formats': False,
                        'retries': 3,
                        'quality': quality,
                    }
                })
            
            # 添加其他浏览器Cookie策略
            for browser in ['safari', 'firefox', 'edge']:
                for fmt in format_options[:2]:  # 只尝试前2个最佳格式
                    strategies.append({
                        "name": f"{browser.title()}自动Cookie-{fmt}",
                        "opts": {
                            'quiet': True,
                            'no_warnings': True,
                            'format': fmt,
                            'cookiesfrombrowser': (browser,),
                            'prefer_free_formats': False,
                            'retries': 2,
                            'quality': quality,
                        }
                    })
            
            logger.info(f"开始尝试{len(strategies)}种高清下载策略，目标质量: {quality}")
            
            # 尝试每个策略
            for i, strategy in enumerate(strategies):
                try:
                    logger.info(f"尝试策略 {i+1}/{len(strategies)}: {strategy['name']}")
                    
                    def _extract_info():
                        with yt_dlp.YoutubeDL(strategy["opts"]) as ydl:
                            return ydl.extract_info(youtube_url, download=False)
                    
                    loop = asyncio.get_event_loop()
                    info = await loop.run_in_executor(None, _extract_info)
                    
                    if info and info.get('url'):
                        # 验证获取的分辨率
                        height = info.get('height', 0)
                        width = info.get('width', 0)
                        resolution = info.get('resolution', f"{width}x{height}")
                        vcodec = info.get('vcodec', 'unknown')
                        acodec = info.get('acodec', 'unknown')
                        filesize = info.get('filesize_approx', info.get('filesize', 0))
                        
                        # 验证是否符合高清要求
                        is_hd = height >= 720
                        is_full_hd = height >= 1080
                        is_h264 = 'avc1' in vcodec.lower() if vcodec else False
                        
                        result = {
                            "video_id": info.get('id'),
                            "title": info.get('title'),
                            "download_url": info.get('url'),
                            "format": info.get('ext'),
                            "resolution": resolution,
                            "width": width,
                            "height": height,
                            "filesize": info.get('filesize'),
                            "filesize_approx": filesize,
                            "duration": info.get('duration'),
                            "thumbnail": info.get('thumbnail'),
                            "strategy_used": strategy["name"],
                            "format_id": info.get('format_id'),
                            "acodec": acodec,
                            "vcodec": vcodec,
                            "has_audio": info.get('acodec') != 'none',
                            "yt_dlp_version": "2025.6.30",
                            "is_hd": is_hd,
                            "is_full_hd": is_full_hd,
                            "is_h264": is_h264,
                            "quality_verified": True,
                            "fps": info.get('fps'),
                            "tbr": info.get('tbr'),
                            "format_note": info.get('format_note')
                        }
                        
                        # 根据质量判断是否接受
                        if quality in ['1080p', '1080p60'] and not is_full_hd:
                            logger.warning(f"策略 {strategy['name']} 获取到 {height}p，低于要求的1080p，继续尝试下一个策略")
                            continue
                        elif quality in ['720p', '720p60'] and not is_hd:
                            logger.warning(f"策略 {strategy['name']} 获取到 {height}p，低于要求的720p，继续尝试下一个策略")
                            continue
                        
                        logger.info(f"✅ 高清策略成功! {strategy['name']}")
                        logger.info(f"📺 分辨率: {resolution} ({height}p)")
                        logger.info(f"🎬 编解码器: {vcodec} / {acodec}")
                        logger.info(f"📦 文件大小: {filesize/1024/1024:.1f}MB" if filesize else "文件大小: 未知")
                        logger.info(f"⚡ 格式ID: {info.get('format_id')}")
                        
                        return {
                            "success": True,
                            "data": result
                        }
                        
                except Exception as strategy_error:
                    error_msg = str(strategy_error)
                    # 简化错误日志
                    if "Sign in to confirm you're not a bot" in error_msg:
                        logger.debug(f"策略 {strategy['name']} 遇到机器人检测")
                    elif "format is not available" in error_msg.lower():
                        logger.debug(f"策略 {strategy['name']} 请求的格式不可用")
                    elif any(keyword in error_msg.lower() for keyword in ["cookies", "browser", "private", "unavailable"]):
                        logger.debug(f"策略 {strategy['name']} 无法访问")
                    else:
                        logger.warning(f"策略 {strategy['name']} 失败: {error_msg[:100]}...")
                    continue
            
            # 所有高清策略都失败，提供用户选择
            logger.warning("🚨 所有高清策略都失败，尝试降级到可用的最佳质量")
            
            # 降级策略：获取任何可用质量
            fallback_formats = [
                "best[height>=480][vcodec!^=av01]",  # 至少480p，排除AV1
                "best[vcodec!^=av01]",              # 任何质量，排除AV1
                "best"                              # 最后兜底
            ]
            
            for fmt in fallback_formats:
                try:
                    logger.info(f"尝试降级格式: {fmt}")
                    
                    fallback_opts = {
                        'quiet': True,
                        'no_warnings': True,
                        'format': fmt,
                        'cookiesfrombrowser': ('chrome',),
                        'prefer_free_formats': False,
                        'retries': 2,
                    }
                    
                    def _extract_fallback():
                        with yt_dlp.YoutubeDL(fallback_opts) as ydl:
                            return ydl.extract_info(youtube_url, download=False)
                    
                    loop = asyncio.get_event_loop()
                    info = await loop.run_in_executor(None, _extract_fallback)
                    
                    if info and info.get('url'):
                        height = info.get('height', 0)
                        
                        result = {
                            "video_id": info.get('id'),
                            "title": info.get('title'),
                            "download_url": info.get('url'),
                            "format": info.get('ext'),
                            "resolution": info.get('resolution') or f"{info.get('width', 'unknown')}x{height}",
                            "height": height,
                            "width": info.get('width', 0),
                            "filesize": info.get('filesize'),
                            "filesize_approx": info.get('filesize_approx'),
                            "duration": info.get('duration'),
                            "thumbnail": info.get('thumbnail'),
                            "strategy_used": f"降级策略-{fmt}",
                            "format_id": info.get('format_id'),
                            "acodec": info.get('acodec'),
                            "vcodec": info.get('vcodec'),
                            "has_audio": info.get('acodec') != 'none',
                            "yt_dlp_version": "2025.6.30",
                            "is_hd": height >= 720,
                            "is_full_hd": height >= 1080,
                            "quality_verified": False,
                            "warning": f"获取到{height}p视频，低于请求的{quality}质量"
                        }
                        
                        logger.warning(f"⚠️  降级成功，获取到 {height}p 视频 (请求: {quality})")
                        
                        return {
                            "success": True,
                            "data": result
                        }
                        
                except Exception as e:
                    logger.debug(f"降级格式 {fmt} 失败: {str(e)[:50]}...")
                    continue
            
            # 所有方法都失败
            return {
                "success": False,
                "error": f"无法获取{quality}高清视频。尝试了{len(strategies)}种高清策略和{len(fallback_formats)}种降级方案都失败。可能原因：1)视频需要登录访问 2)地区限制 3)视频已被删除 4)YouTube反机器人检测加强。建议稍后重试或联系技术支持。",
                "yt_dlp_version": "2025.6.30",
                "strategies_tried": len(strategies),
                "requested_quality": quality
            }
            
        except Exception as e:
            logger.error(f"高级YouTube下载链接获取失败: {str(e)}")
            return {
                "success": False,
                "error": f"高级下载链接获取失败: {str(e)}",
                "yt_dlp_version": "2025.6.30"
            }

    async def get_download_urls_with_pytube_fallback(self, youtube_url: str, quality: str = "720p") -> Dict[str, Any]:
        """使用pytube作为备用方案获取YouTube视频下载链接"""
        try:
            if not self._is_youtube_url(youtube_url):
                return {
                    "success": False,
                    "error": "不是有效的YouTube链接"
                }
            
            # 首先尝试主要的yt-dlp方法
            logger.info("尝试主要的yt-dlp方法...")
            main_result = await self.get_download_urls_advanced(youtube_url, quality)
            
            if main_result["success"]:
                main_result["data"]["primary_method"] = "yt-dlp"
                return main_result
            
            # yt-dlp失败，尝试pytube备用方案
            logger.info("yt-dlp失败，尝试pytube备用方案...")
            
            try:
                import pytube
                
                def _extract_with_pytube():
                    # 创建YouTube对象
                    yt = pytube.YouTube(youtube_url)
                    
                    # 根据质量要求选择流
                    quality_map = {
                        "1080p": "1080p",
                        "720p": "720p", 
                        "480p": "480p",
                        "360p": "360p",
                        "best": None
                    }
                    
                    target_quality = quality_map.get(quality, "720p")
                    
                    # 尝试获取指定质量的流
                    stream = None
                    
                    if target_quality:
                        # 优先尝试progressive流（包含音频和视频）
                        stream = yt.streams.filter(
                            progressive=True, 
                            file_extension='mp4',
                            res=target_quality
                        ).first()
                        
                        # 如果没有progressive流，尝试adaptive流（仅视频）
                        if not stream:
                            stream = yt.streams.filter(
                                adaptive=True,
                                file_extension='mp4',
                                res=target_quality,
                                only_video=True
                            ).first()
                    
                    # 如果指定质量不可用，获取最佳可用质量
                    if not stream:
                        # 尝试获取最高质量的progressive流
                        stream = yt.streams.filter(
                            progressive=True,
                            file_extension='mp4'
                        ).order_by('resolution').desc().first()
                        
                        # 如果还是没有，获取最高质量的adaptive流
                        if not stream:
                            stream = yt.streams.filter(
                                adaptive=True,
                                file_extension='mp4',
                                only_video=True
                            ).order_by('resolution').desc().first()
                    
                    if not stream:
                        raise Exception("未找到可用的视频流")
                    
                    # 解析分辨率信息
                    resolution_str = stream.resolution or "unknown"
                    height = 0
                    if resolution_str and resolution_str != "unknown":
                        height = int(resolution_str.replace('p', ''))
                    
                    # 检查是否有音频
                    has_audio = stream.includes_audio_track if hasattr(stream, 'includes_audio_track') else (not stream.adaptive)
                    
                    return {
                        "video_id": yt.video_id,
                        "title": yt.title,
                        "download_url": stream.url,
                        "format": "mp4",
                        "resolution": resolution_str,
                        "height": height,
                        "width": None,  # pytube不提供宽度信息
                        "filesize": stream.filesize,
                        "filesize_approx": stream.filesize,
                        "duration": yt.length,
                        "thumbnail": yt.thumbnail_url,
                        "strategy_used": "pytube备用方案",
                        "format_id": f"pytube-{stream.itag}",
                        "acodec": "aac" if has_audio else "none",
                        "vcodec": "h264",  # pytube主要使用h264
                        "has_audio": has_audio,
                        "yt_dlp_version": "pytube-15.0.0",
                        "is_hd": height >= 720,
                        "is_full_hd": height >= 1080,
                        "quality_verified": True,
                        "fps": None,  # pytube不提供FPS信息
                        "tbr": stream.bitrate,
                        "pytube_itag": stream.itag,
                        "progressive": not stream.adaptive,
                        "view_count": yt.views,
                        "author": yt.author
                    }
                
                # 在线程池中执行pytube操作
                loop = asyncio.get_event_loop()
                result_data = await loop.run_in_executor(None, _extract_with_pytube)
                
                # 验证质量是否符合要求
                if quality in ['1080p'] and result_data['height'] < 1080:
                    logger.warning(f"pytube获取到{result_data['height']}p，低于要求的1080p")
                    result_data['warning'] = f"获取到{result_data['height']}p视频，低于请求的{quality}质量"
                elif quality in ['720p'] and result_data['height'] < 720:
                    logger.warning(f"pytube获取到{result_data['height']}p，低于要求的720p")
                    result_data['warning'] = f"获取到{result_data['height']}p视频，低于请求的{quality}质量"
                
                logger.info(f"✅ pytube备用方案成功!")
                logger.info(f"📺 标题: {result_data['title']}")
                logger.info(f"📏 分辨率: {result_data['resolution']} ({result_data['height']}p)")
                logger.info(f"🎬 编解码器: {result_data['vcodec']} / {result_data['acodec']}")
                logger.info(f"📦 文件大小: {result_data['filesize']/1024/1024:.1f}MB" if result_data['filesize'] else "文件大小: 未知")
                logger.info(f"🎵 音频: {'有' if result_data['has_audio'] else '无'}")
                logger.info(f"📊 渐进式: {'是' if result_data['progressive'] else '否'}")
                
                return {
                    "success": True,
                    "data": result_data
                }
                
            except ImportError:
                logger.error("pytube库未安装，请运行: pip install pytube")
                return {
                    "success": False,
                    "error": "pytube库未安装，请运行: pip install pytube"
                }
            except Exception as e:
                logger.error(f"pytube备用方案也失败: {str(e)}")
                return {
                    "success": False,
                    "error": f"主要方法和pytube备用方案都失败。主要错误: {main_result['error']}，备用错误: {str(e)}"
                }
            
        except Exception as e:
            logger.error(f"YouTube下载链接获取失败(包含备用方案): {str(e)}")
            return {
                "success": False,
                "error": f"下载链接获取失败: {str(e)}"
            }

    async def get_download_urls_with_pytube_ssl_bypass(self, youtube_url: str, quality: str = "720p") -> Dict[str, Any]:
        """使用SSL绕过的pytube获取YouTube视频下载链接"""
        try:
            if not self._is_youtube_url(youtube_url):
                return {
                    "success": False,
                    "error": "不是有效的YouTube链接"
                }
            
            logger.info("尝试使用SSL绕过的pytube方案...")
            
            try:
                import pytube
                import ssl
                import urllib3
                from urllib3.exceptions import InsecureRequestWarning
                
                # 禁用SSL警告
                urllib3.disable_warnings(InsecureRequestWarning)
                
                def _extract_with_ssl_bypass():
                    # 创建自定义的SSL上下文
                    ssl_context = ssl.create_default_context()
                    ssl_context.check_hostname = False
                    ssl_context.verify_mode = ssl.CERT_NONE
                    
                    # 临时修改pytube的请求方法
                    original_request = pytube.request.get
                    
                    def patched_request(url, headers=None, **kwargs):
                        import urllib.request
                        import urllib.parse
                        
                        req = urllib.request.Request(url, headers=headers or {})
                        try:
                            # 使用自定义SSL上下文
                            response = urllib.request.urlopen(req, context=ssl_context)
                            return response.read().decode('utf-8')
                        except Exception as e:
                            # 如果SSL失败，尝试不验证SSL
                            try:
                                response = urllib.request.urlopen(req, context=ssl.create_default_context())
                                return response.read().decode('utf-8')
                            except:
                                raise e
                    
                    # 临时替换请求方法
                    pytube.request.get = patched_request
                    
                    try:
                        # 创建YouTube对象
                        yt = pytube.YouTube(youtube_url)
                        
                        # 根据质量选择流
                        quality_preferences = {
                            "1080p": ["1080p"],
                            "720p": ["720p", "480p"],
                            "480p": ["480p", "360p"],
                            "360p": ["360p"],
                            "best": ["1080p", "720p", "480p", "360p"]
                        }
                        
                        target_qualities = quality_preferences.get(quality, ["720p", "480p"])
                        stream = None
                        
                        # 尝试按质量优先级获取流
                        for target_quality in target_qualities:
                            # 先尝试渐进式流（包含音频）
                            stream = yt.streams.filter(
                                progressive=True,
                                file_extension='mp4',
                                res=target_quality
                            ).first()
                            
                            if stream:
                                break
                            
                            # 再尝试自适应流（仅视频）
                            stream = yt.streams.filter(
                                adaptive=True,
                                file_extension='mp4',
                                res=target_quality,
                                only_video=True
                            ).first()
                            
                            if stream:
                                break
                        
                        # 如果没找到指定质量，获取最佳可用
                        if not stream:
                            stream = yt.streams.filter(
                                progressive=True,
                                file_extension='mp4'
                            ).order_by('resolution').desc().first()
                        
                        if not stream:
                            stream = yt.streams.filter(
                                adaptive=True,
                                file_extension='mp4',
                                only_video=True
                            ).order_by('resolution').desc().first()
                        
                        if not stream:
                            raise Exception("未找到任何可用的视频流")
                        
                        # 获取下载URL
                        download_url = stream.url
                        
                        # 解析分辨率
                        resolution_str = stream.resolution or "unknown"
                        height = 0
                        if resolution_str != "unknown":
                            height = int(resolution_str.replace('p', ''))
                        
                        # 检查音频
                        has_audio = not stream.adaptive
                        
                        result = {
                            "video_id": yt.video_id,
                            "title": yt.title,
                            "download_url": download_url,
                            "format": "mp4",
                            "resolution": resolution_str,
                            "height": height,
                            "width": None,
                            "filesize": stream.filesize,
                            "filesize_approx": stream.filesize,
                            "duration": yt.length,
                            "thumbnail": yt.thumbnail_url,
                            "strategy_used": "pytube-SSL-bypass",
                            "format_id": f"pytube-ssl-{stream.itag}",
                            "acodec": "aac" if has_audio else "none",
                            "vcodec": "h264",
                            "has_audio": has_audio,
                            "yt_dlp_version": "pytube-15.0.0-ssl-bypass",
                            "is_hd": height >= 720,
                            "is_full_hd": height >= 1080,
                            "quality_verified": True,
                            "fps": None,
                            "tbr": stream.bitrate,
                            "pytube_itag": stream.itag,
                            "progressive": not stream.adaptive,
                            "view_count": yt.views,
                            "author": yt.author,
                            "ssl_bypass": True
                        }
                        
                        return result
                        
                    finally:
                        # 恢复原始请求方法
                        pytube.request.get = original_request
                
                # 在线程池中执行
                loop = asyncio.get_event_loop()
                result_data = await loop.run_in_executor(None, _extract_with_ssl_bypass)
                
                # 验证质量
                requested_height = {"1080p": 1080, "720p": 720, "480p": 480, "360p": 360}.get(quality, 720)
                if result_data['height'] < requested_height:
                    result_data['warning'] = f"获取到{result_data['height']}p视频，低于请求的{quality}质量"
                
                logger.info(f"✅ SSL绕过pytube方案成功!")
                logger.info(f"📺 标题: {result_data['title']}")
                logger.info(f"📏 分辨率: {result_data['resolution']} ({result_data['height']}p)")
                logger.info(f"🎬 编解码器: {result_data['vcodec']} / {result_data['acodec']}")
                logger.info(f"📦 文件大小: {result_data['filesize']/1024/1024:.1f}MB" if result_data['filesize'] else "文件大小: 未知")
                logger.info(f"🎵 音频: {'有' if result_data['has_audio'] else '无'}")
                logger.info(f"👁️  观看次数: {result_data['view_count']:,}")
                logger.info(f"👤 作者: {result_data['author']}")
                
                return {
                    "success": True,
                    "data": result_data
                }
                
            except ImportError:
                return {
                    "success": False,
                    "error": "pytube库未安装，请运行: pip install pytube"
                }
            except Exception as e:
                logger.error(f"SSL绕过pytube方案失败: {str(e)}")
                return {
                    "success": False,
                    "error": f"SSL绕过pytube方案失败: {str(e)}"
                }
            
        except Exception as e:
            logger.error(f"YouTube下载链接获取失败(SSL绕过): {str(e)}")
            return {
                "success": False,
                "error": f"下载链接获取失败: {str(e)}"
            }

    def _get_proxy_config(self):
        """获取代理配置"""
        import os
        
        # 从环境变量获取代理设置
        http_proxy = os.environ.get('HTTP_PROXY') or os.environ.get('http_proxy')
        https_proxy = os.environ.get('HTTPS_PROXY') or os.environ.get('https_proxy')
        
        # 常见的VPN代理端口配置
        common_proxies = [
            'socks5://127.0.0.1:1080',  # 常见的SOCKS5代理
            'http://127.0.0.1:8080',    # 常见的HTTP代理
            'http://127.0.0.1:1087',    # Clash等工具常用端口
            'socks5://127.0.0.1:7890',  # Clash SOCKS5端口
        ]
        
        proxy_config = {}
        
        if http_proxy or https_proxy:
            proxy_config['proxy'] = https_proxy or http_proxy
            logger.info(f"🌐 使用环境变量代理: {proxy_config['proxy']}")
        else:
            # 尝试检测常见代理端口
            import socket
            for proxy in common_proxies:
                try:
                    if proxy.startswith('socks5://'):
                        host, port = proxy.replace('socks5://', '').split(':')
                    else:
                        host, port = proxy.replace('http://', '').split(':')
                    
                    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                    sock.settimeout(1)
                    result = sock.connect_ex((host, int(port)))
                    sock.close()
                    
                    if result == 0:
                        proxy_config['proxy'] = proxy
                        logger.info(f"🌐 自动检测到代理: {proxy}")
                        break
                except:
                    continue
        
        return proxy_config

    async def get_download_urls_with_proxy(self, youtube_url: str, quality: str = "720p") -> Dict[str, Any]:
        """使用代理获取YouTube视频下载链接"""
        try:
            if not self._is_youtube_url(youtube_url):
                return {
                    "success": False,
                    "error": "不是有效的YouTube链接"
                }
            
            # 获取代理配置
            proxy_config = self._get_proxy_config()
            
            if not proxy_config:
                logger.warning("⚠️  未检测到代理配置，建议配置VPN代理以提高成功率")
                # 回退到普通方法
                return await self.get_download_urls_advanced(youtube_url, quality)
            
            logger.info(f"🚀 使用代理尝试获取YouTube视频: {quality}")
            
            # 高清格式配置（与之前相同）
            quality_format_map = {
                "1080p": [
                    "137+140",
                    "bestvideo[height>=1080][vcodec^=avc1]+bestaudio[acodec^=mp4a]",
                    "bestvideo[height>=1080][vcodec!^=av01]+bestaudio",
                    "best[height>=1080][vcodec!^=av01]"
                ],
                "720p": [
                    "136+140",
                    "bestvideo[height>=720][vcodec^=avc1]+bestaudio[acodec^=mp4a]",
                    "bestvideo[height>=720][vcodec!^=av01]+bestaudio",
                    "best[height>=720][vcodec!^=av01]"
                ]
            }
            
            format_options = quality_format_map.get(quality, quality_format_map["720p"])
            
            # 检查手动cookie
            manual_cookie_path = self._get_manual_cookie_path()
            
            # 代理策略配置
            strategies = []
            
            # 手动cookie + 代理
            if manual_cookie_path:
                for fmt in format_options[:2]:  # 只尝试前2个最佳格式
                    strategies.append({
                        "name": f"手动Cookie+代理-{fmt}",
                        "opts": {
                            'quiet': False,
                            'no_warnings': False,
                            'format': fmt,
                            'cookiefile': manual_cookie_path,
                            'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
                            'prefer_free_formats': False,
                            'retries': 3,
                            **proxy_config
                        }
                    })
            
            # Chrome cookies + 代理
            for fmt in format_options[:3]:
                strategies.append({
                    "name": f"Chrome+代理-{fmt}",
                    "opts": {
                        'quiet': True,
                        'no_warnings': True,
                        'format': fmt,
                        'cookiesfrombrowser': ('chrome',),
                        'user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
                        'prefer_free_formats': False,
                        'retries': 2,
                        **proxy_config
                    }
                })
            
            # 尝试每个策略
            for i, strategy in enumerate(strategies):
                try:
                    logger.info(f"🌐 尝试代理策略 {i+1}/{len(strategies)}: {strategy['name']}")
                    
                    def _extract_info():
                        with yt_dlp.YoutubeDL(strategy["opts"]) as ydl:
                            return ydl.extract_info(youtube_url, download=False)
                    
                    loop = asyncio.get_event_loop()
                    info = await loop.run_in_executor(None, _extract_info)
                    
                    if info and info.get('url'):
                        # 验证质量
                        height = info.get('height', 0)
                        width = info.get('width', 0)
                        vcodec = info.get('vcodec', 'unknown')
                        acodec = info.get('acodec', 'unknown')
                        filesize = info.get('filesize_approx', info.get('filesize', 0))
                        
                        # 质量检查
                        is_hd = height >= 720
                        is_full_hd = height >= 1080
                        
                        result = {
                            "video_id": info.get('id'),
                            "title": info.get('title'),
                            "download_url": info.get('url'),
                            "format": info.get('ext'),
                            "resolution": info.get('resolution', f"{width}x{height}"),
                            "width": width,
                            "height": height,
                            "filesize": info.get('filesize'),
                            "filesize_approx": filesize,
                            "duration": info.get('duration'),
                            "thumbnail": info.get('thumbnail'),
                            "strategy_used": f"{strategy['name']} (通过代理)",
                            "format_id": info.get('format_id'),
                            "acodec": acodec,
                            "vcodec": vcodec,
                            "has_audio": info.get('acodec') != 'none',
                            "yt_dlp_version": "2025.6.30-proxy",
                            "is_hd": is_hd,
                            "is_full_hd": is_full_hd,
                            "quality_verified": True,
                            "fps": info.get('fps'),
                            "tbr": info.get('tbr'),
                            "proxy_used": proxy_config.get('proxy', 'unknown')
                        }
                        
                        # 质量验证
                        if quality in ['1080p'] and not is_full_hd:
                            logger.warning(f"代理策略获取到{height}p，低于要求的1080p，继续尝试")
                            continue
                        elif quality in ['720p'] and not is_hd:
                            logger.warning(f"代理策略获取到{height}p，低于要求的720p，继续尝试")
                            continue
                        
                        logger.info(f"✅ 代理策略成功! {strategy['name']}")
                        logger.info(f"🌐 使用代理: {proxy_config.get('proxy')}")
                        logger.info(f"📺 分辨率: {width}x{height} ({height}p)")
                        logger.info(f"🎬 编解码器: {vcodec} / {acodec}")
                        logger.info(f"📦 文件大小: {filesize/1024/1024:.1f}MB" if filesize else "文件大小: 未知")
                        
                        return {
                            "success": True,
                            "data": result
                        }
                        
                except Exception as e:
                    error_msg = str(e)
                    if "Sign in to confirm you're not a bot" in error_msg:
                        logger.debug(f"代理策略 {strategy['name']} 仍遇到机器人检测")
                    elif "Connection" in error_msg or "proxy" in error_msg.lower():
                        logger.warning(f"代理连接问题: {strategy['name']} - {error_msg[:50]}...")
                    else:
                        logger.debug(f"代理策略 {strategy['name']} 失败: {error_msg[:50]}...")
                    continue
            
            # 所有代理策略失败
            return {
                "success": False,
                "error": f"所有代理策略都失败。代理: {proxy_config.get('proxy', '未配置')}。建议检查VPN连接和代理设置。",
                "proxy_used": proxy_config.get('proxy'),
                "strategies_tried": len(strategies)
            }
            
        except Exception as e:
            logger.error(f"代理YouTube下载失败: {str(e)}")
            return {
                "success": False,
                "error": f"代理下载失败: {str(e)}"
            }

    async def get_download_urls_no_cookies(self, youtube_url: str, quality: str = "720p") -> Dict[str, Any]:
        """不使用cookie获取YouTube视频下载链接 - 仅适用于公开视频"""
        try:
            if not self._is_youtube_url(youtube_url):
                return {
                    "success": False,
                    "error": "不是有效的YouTube链接"
                }
            
            logger.info(f"🚫 尝试无Cookie方式获取YouTube视频: {quality}")
            
            # 获取代理配置
            proxy_config = self._get_proxy_config()
            
            # 高清格式配置
            quality_format_map = {
                "1080p": [
                    "137+140",  # 1080p H.264 + AAC
                    "bestvideo[height>=1080][vcodec^=avc1]+bestaudio[acodec^=mp4a]",
                    "bestvideo[height>=1080][vcodec!^=av01]+bestaudio",
                    "best[height>=1080][vcodec!^=av01]"
                ],
                "720p": [
                    "136+140",  # 720p H.264 + AAC
                    "bestvideo[height>=720][vcodec^=avc1]+bestaudio[acodec^=mp4a]",
                    "bestvideo[height>=720][vcodec!^=av01]+bestaudio",
                    "best[height>=720][vcodec!^=av01]"
                ],
                "480p": [
                    "best[height>=480][vcodec!^=av01]",
                    "best[height>=480]"
                ],
                "best": [
                    "bestvideo[vcodec^=avc1]+bestaudio[acodec^=mp4a]",
                    "bestvideo[vcodec!^=av01]+bestaudio",
                    "best[vcodec!^=av01]",
                    "best"
                ]
            }
            
            format_options = quality_format_map.get(quality, quality_format_map["720p"])
            
            # 无Cookie策略配置
            strategies = []
            
            # 策略1: 代理 + 基础配置
            if proxy_config:
                for fmt in format_options[:2]:
                    strategies.append({
                        "name": f"代理无Cookie-{fmt}",
                        "opts": {
                            'quiet': False,
                            'no_warnings': False,
                            'format': fmt,
                            'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
                            'prefer_free_formats': False,
                            'retries': 3,
                            'socket_timeout': 30,
                            **proxy_config
                        }
                    })
            
            # 策略2: 直连 + 基础配置（如果没有代理）
            for fmt in format_options[:3]:
                strategies.append({
                    "name": f"直连无Cookie-{fmt}",
                    "opts": {
                        'quiet': True,
                        'no_warnings': True,
                        'format': fmt,
                        'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
                        'prefer_free_formats': False,
                        'retries': 2,
                        'socket_timeout': 30,
                    }
                })
            
            # 策略3: 嵌入式播放器
            strategies.append({
                "name": "嵌入式播放器无Cookie",
                "opts": {
                    'quiet': True,
                    'no_warnings': True,
                    'format': 'best[height<=720][vcodec!^=av01]/best',
                    'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
                    'extractor_args': {
                        'youtube': {
                            'player_client': ['web_embedded'],
                            'player_skip': ['configs'],
                        }
                    },
                    'socket_timeout': 30,
                    **(proxy_config if proxy_config else {})
                }
            })
            
            # 策略4: 移动端模拟
            strategies.append({
                "name": "移动端无Cookie",
                "opts": {
                    'quiet': True,
                    'no_warnings': True,
                    'format': 'best[height<=720]/best',
                    'user_agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1',
                    'extractor_args': {
                        'youtube': {
                            'player_client': ['mweb'],
                        }
                    },
                    'socket_timeout': 30,
                    **(proxy_config if proxy_config else {})
                }
            })
            
            # 策略5: 最简配置
            strategies.append({
                "name": "最简无Cookie",
                "opts": {
                    'quiet': True,
                    'no_warnings': True,
                    'format': 'best',
                    'socket_timeout': 30,
                    **(proxy_config if proxy_config else {})
                }
            })
            
            logger.info(f"🚫 开始尝试{len(strategies)}种无Cookie策略")
            if proxy_config:
                logger.info(f"🌐 使用代理: {proxy_config.get('proxy')}")
            
            # 尝试每个策略
            for i, strategy in enumerate(strategies):
                try:
                    logger.info(f"🚫 尝试策略 {i+1}/{len(strategies)}: {strategy['name']}")
                    
                    def _extract_info():
                        with yt_dlp.YoutubeDL(strategy["opts"]) as ydl:
                            return ydl.extract_info(youtube_url, download=False)
                    
                    loop = asyncio.get_event_loop()
                    info = await loop.run_in_executor(None, _extract_info)
                    
                    if info and info.get('url'):
                        # 验证质量
                        height = info.get('height', 0)
                        width = info.get('width', 0)
                        vcodec = info.get('vcodec', 'unknown')
                        acodec = info.get('acodec', 'unknown')
                        filesize = info.get('filesize_approx', info.get('filesize', 0))
                        
                        # 质量检查
                        is_hd = height >= 720
                        is_full_hd = height >= 1080
                        
                        result = {
                            "video_id": info.get('id'),
                            "title": info.get('title'),
                            "download_url": info.get('url'),
                            "format": info.get('ext'),
                            "resolution": info.get('resolution', f"{width}x{height}"),
                            "width": width,
                            "height": height,
                            "filesize": info.get('filesize'),
                            "filesize_approx": filesize,
                            "duration": info.get('duration'),
                            "thumbnail": info.get('thumbnail'),
                            "strategy_used": f"{strategy['name']} (无Cookie)",
                            "format_id": info.get('format_id'),
                            "acodec": acodec,
                            "vcodec": vcodec,
                            "has_audio": info.get('acodec') != 'none',
                            "yt_dlp_version": "2025.6.30-no-cookies",
                            "is_hd": is_hd,
                            "is_full_hd": is_full_hd,
                            "quality_verified": True,
                            "fps": info.get('fps'),
                            "tbr": info.get('tbr'),
                            "cookies_used": False,
                            "proxy_used": proxy_config.get('proxy') if proxy_config else None
                        }
                        
                        # 质量验证（放宽要求，因为无Cookie可能限制质量）
                        if quality == '1080p' and height < 1080:
                            if height >= 720:
                                result['warning'] = f"无Cookie模式获取到{height}p，可能无法访问1080p"
                            else:
                                logger.warning(f"无Cookie策略获取到{height}p，低于720p，继续尝试")
                                continue
                        elif quality == '720p' and height < 720:
                            if height >= 480:
                                result['warning'] = f"无Cookie模式获取到{height}p，可能无法访问720p"
                            else:
                                logger.warning(f"无Cookie策略获取到{height}p，低于480p，继续尝试")
                                continue
                        
                        logger.info(f"✅ 无Cookie策略成功! {strategy['name']}")
                        logger.info(f"📺 分辨率: {width}x{height} ({height}p)")
                        logger.info(f"🎬 编解码器: {vcodec} / {acodec}")
                        logger.info(f"📦 文件大小: {filesize/1024/1024:.1f}MB" if filesize else "文件大小: 未知")
                        logger.info(f"🚫 Cookie: 未使用")
                        logger.info(f"🌐 代理: {proxy_config.get('proxy') if proxy_config else '直连'}")
                        
                        return {
                            "success": True,
                            "data": result
                        }
                        
                except Exception as e:
                    error_msg = str(e)
                    if "Sign in to confirm you're not a bot" in error_msg:
                        logger.debug(f"无Cookie策略 {strategy['name']} 遇到机器人检测")
                    elif "Private video" in error_msg or "requires" in error_msg.lower():
                        logger.debug(f"无Cookie策略 {strategy['name']} 遇到私有视频或权限限制")
                    elif "format is not available" in error_msg.lower():
                        logger.debug(f"无Cookie策略 {strategy['name']} 请求的格式不可用")
                    else:
                        logger.debug(f"无Cookie策略 {strategy['name']} 失败: {error_msg[:50]}...")
                    continue
            
            # 所有策略都失败
            return {
                "success": False,
                "error": f"所有无Cookie策略都失败。这可能表示：1)视频需要登录访问 2)视频是私有的 3)YouTube加强了对公开视频的限制。代理状态: {'使用' if proxy_config else '未使用'}",
                "cookies_used": False,
                "proxy_used": proxy_config.get('proxy') if proxy_config else None,
                "strategies_tried": len(strategies)
            }
            
        except Exception as e:
            logger.error(f"无Cookie YouTube下载失败: {str(e)}")
            return {
                "success": False,
                "error": f"无Cookie下载失败: {str(e)}",
                "cookies_used": False
            } 

    async def get_hls_streams_and_merge(self, youtube_url: str, quality: str = "720p") -> Dict[str, Any]:
        """通过HLS流解析和FFmpeg合成获取高清YouTube视频"""
        try:
            if not self._is_youtube_url(youtube_url):
                return {
                    "success": False,
                    "error": "不是有效的YouTube链接"
                }
            
            logger.info(f"🎬 尝试HLS流解析方法获取YouTube视频: {quality}")
            
            import requests
            import re
            import json
            import tempfile
            import os
            from urllib.parse import urljoin, urlparse
            
            # 获取代理配置
            proxy_config = self._get_proxy_config()
            proxies = None
            if proxy_config and 'proxy' in proxy_config:
                proxies = {
                    'http': proxy_config['proxy'],
                    'https': proxy_config['proxy']
                }
                logger.info(f"🌐 使用代理进行HLS解析: {proxy_config['proxy']}")
            
            # 第一步：获取视频页面
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
                'Accept-Language': 'en-US,en;q=0.5',
                'Accept-Encoding': 'gzip, deflate',
                'DNT': '1',
                'Connection': 'keep-alive',
                'Upgrade-Insecure-Requests': '1',
            }
            
            logger.info("📄 正在获取YouTube视频页面...")
            
            # 配置SSL和连接参数
            session = requests.Session()
            session.headers.update(headers)
            if proxies:
                session.proxies.update(proxies)
            
            # 禁用SSL验证（仅用于测试代理连接）
            session.verify = False
            
            # 禁用SSL警告
            import urllib3
            urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
            
            response = session.get(youtube_url, timeout=30)
            response.raise_for_status()
            
            html_content = response.text
            
            # 第二步：解析播放器配置
            logger.info("🔍 正在解析播放器配置...")
            
            # 提取视频ID
            video_id_match = re.search(r'["\']videoId["\']\s*:\s*["\']([^"\']+)["\']', html_content)
            if not video_id_match:
                # 尝试从URL提取
                url_match = re.search(r'(?:v=|shorts/)([a-zA-Z0-9_-]{11})', youtube_url)
                video_id = url_match.group(1) if url_match else None
            else:
                video_id = video_id_match.group(1)
            
            if not video_id:
                return {
                    "success": False,
                    "error": "无法从页面提取视频ID"
                }
            
            # 提取播放器响应数据
            logger.info("🔍 开始查找播放器配置...")
            
            # 方法1: 查找 ytInitialPlayerResponse
            player_response_match = re.search(r'var ytInitialPlayerResponse = ({.+?});', html_content)
            
            if not player_response_match:
                logger.info("方法1失败，尝试方法2...")
                # 方法2: 查找 playerResponse
                player_response_match = re.search(r'"playerResponse"\s*:\s*"({.+?})"', html_content)
                if player_response_match:
                    # 需要解码
                    import json
                    player_response_str = player_response_match.group(1).replace('\\"', '"')
                    logger.info("方法2成功找到播放器配置")
                else:
                    logger.info("方法2失败，尝试方法3...")
                    # 方法3: 查找 ytInitialPlayerResponse (不同格式)
                    player_response_match = re.search(r'ytInitialPlayerResponse["\'\s]*[:=]["\'\s]*({.+?})[;,]', html_content)
                    if player_response_match:
                        player_response_str = player_response_match.group(1)
                        logger.info("方法3成功找到播放器配置")
                    else:
                        logger.error("所有方法都失败了")
                        # 保存页面内容用于调试
                        with open('/tmp/youtube_debug.html', 'w', encoding='utf-8') as f:
                            f.write(html_content[:10000])  # 只保存前10000字符
                        logger.info("已将页面前10000字符保存到 /tmp/youtube_debug.html 用于调试")
                        return {
                            "success": False,
                            "error": "无法从页面提取播放器配置，已保存调试信息"
                        }
            else:
                player_response_str = player_response_match.group(1)
                logger.info("方法1成功找到播放器配置")
            
            try:
                player_response = json.loads(player_response_str)
            except json.JSONDecodeError as e:
                return {
                    "success": False,
                    "error": f"播放器配置解析失败: {str(e)}"
                }
            
            # 第三步：提取流信息
            logger.info("🎯 正在提取HLS流信息...")
            
            video_details = player_response.get('videoDetails', {})
            streaming_data = player_response.get('streamingData', {})
            
            # 调试信息
            logger.info(f"📊 播放器配置keys: {list(player_response.keys())}")
            logger.info(f"📺 视频详情keys: {list(video_details.keys()) if video_details else 'None'}")
            logger.info(f"🎬 流数据keys: {list(streaming_data.keys()) if streaming_data else 'None'}")
            
            if video_details:
                title = video_details.get('title', 'Unknown')
                is_live = video_details.get('isLive', False)
                is_private = video_details.get('isPrivate', False)
                logger.info(f"📋 视频标题: {title}")
                logger.info(f"🔴 是否直播: {is_live}")
                logger.info(f"🔒 是否私有: {is_private}")
            
            if not streaming_data:
                # 检查是否有错误信息
                playability_status = player_response.get('playabilityStatus', {})
                status = playability_status.get('status', 'Unknown')
                reason = playability_status.get('reason', 'No reason provided')
                logger.error(f"📵 播放状态: {status}, 原因: {reason}")
                
                return {
                    "success": False,
                    "error": f"无法获取流数据。状态: {status}, 原因: {reason}"
                }
            
            # 获取自适应格式（分离的音视频流）
            adaptive_formats = streaming_data.get('adaptiveFormats', [])
            formats = streaming_data.get('formats', [])
            
            if not adaptive_formats and not formats:
                return {
                    "success": False,
                    "error": "未找到可用的视频流格式"
                }
            
            # 第四步：选择最佳质量的视频和音频流
            logger.info(f"📊 正在选择{quality}质量的流...")
            
            # 质量映射
            quality_height = {
                "1080p": 1080,
                "720p": 720,
                "480p": 480,
                "360p": 360
            }
            target_height = quality_height.get(quality, 720)
            
            # 选择视频流 (优先H.264)
            video_stream = None
            for fmt in adaptive_formats:
                if fmt.get('mimeType', '').startswith('video/') and fmt.get('url'):
                    height = fmt.get('height', 0)
                    codec = fmt.get('mimeType', '')
                    
                    # 优先选择H.264且符合质量要求的流
                    if height >= target_height and 'avc1' in codec:
                        video_stream = fmt
                        break
                    elif height >= target_height and not video_stream:
                        video_stream = fmt
            
            # 如果没找到目标质量，选择最接近的
            if not video_stream:
                video_streams = [f for f in adaptive_formats if f.get('mimeType', '').startswith('video/') and f.get('url')]
                video_streams.sort(key=lambda x: x.get('height', 0), reverse=True)
                video_stream = video_streams[0] if video_streams else None
            
            # 选择音频流 (优先AAC)
            audio_stream = None
            for fmt in adaptive_formats:
                if fmt.get('mimeType', '').startswith('audio/') and fmt.get('url'):
                    codec = fmt.get('mimeType', '')
                    if 'mp4a' in codec:  # AAC
                        audio_stream = fmt
                        break
                    elif not audio_stream:
                        audio_stream = fmt
            
            if not video_stream:
                return {
                    "success": False,
                    "error": "未找到可用的视频流"
                }
            
            # 第五步：准备下载信息
            video_url = video_stream['url']
            audio_url = audio_stream['url'] if audio_stream else None
            
            video_height = video_stream.get('height', 0)
            video_width = video_stream.get('width', 0)
            video_fps = video_stream.get('fps', 30)
            video_bitrate = video_stream.get('bitrate', 0)
            
            audio_bitrate = audio_stream.get('bitrate', 0) if audio_stream else 0
            
            # 构造结果
            result = {
                "video_id": video_id,
                "title": video_details.get('title', 'Unknown'),
                "video_stream_url": video_url,
                "audio_stream_url": audio_url,
                "format": "mp4",
                "resolution": f"{video_width}x{video_height}",
                "width": video_width,
                "height": video_height,
                "duration": int(video_details.get('lengthSeconds', 0)),
                "thumbnail": video_details.get('thumbnail', {}).get('thumbnails', [{}])[-1].get('url'),
                "strategy_used": "HLS流解析 + FFmpeg合成",
                "format_id": f"hls-{video_stream.get('itag', 'unknown')}",
                "acodec": "aac" if audio_stream else "none",
                "vcodec": "h264" if 'avc1' in video_stream.get('mimeType', '') else "unknown",
                "has_audio": bool(audio_stream),
                "yt_dlp_version": "HLS-Stream-Parser",
                "is_hd": video_height >= 720,
                "is_full_hd": video_height >= 1080,
                "quality_verified": True,
                "fps": video_fps,
                "video_bitrate": video_bitrate,
                "audio_bitrate": audio_bitrate,
                "proxy_used": proxy_config.get('proxy') if proxy_config else None,
                "hls_method": True,
                "video_codec_detail": video_stream.get('mimeType'),
                "audio_codec_detail": audio_stream.get('mimeType') if audio_stream else None,
                "requires_ffmpeg_merge": bool(audio_stream),
                "author": video_details.get('author', 'Unknown'),
                "view_count": int(video_details.get('viewCount', 0))
            }
            
            # 质量验证
            if quality == '1080p' and video_height < 1080:
                result['warning'] = f"HLS解析获取到{video_height}p，可能该视频最高只支持{video_height}p"
            elif quality == '720p' and video_height < 720:
                result['warning'] = f"HLS解析获取到{video_height}p，可能该视频最高只支持{video_height}p"
            
            logger.info(f"✅ HLS流解析成功!")
            logger.info(f"📺 标题: {result['title']}")
            logger.info(f"📏 分辨率: {result['resolution']} ({video_height}p)")
            logger.info(f"🎬 视频编解码器: {result['video_codec_detail']}")
            logger.info(f"🎵 音频编解码器: {result['audio_codec_detail'] or '无音频'}")
            logger.info(f"📊 视频码率: {video_bitrate/1000:.0f}k, 音频码率: {audio_bitrate/1000:.0f}k")
            logger.info(f"🔧 需要FFmpeg合成: {'是' if result['requires_ffmpeg_merge'] else '否'}")
            
            return {
                "success": True,
                "data": result
            }
            
        except requests.RequestException as e:
            logger.error(f"HLS流解析网络请求失败: {str(e)}")
            return {
                "success": False,
                "error": f"网络请求失败: {str(e)}"
            }
        except Exception as e:
            logger.error(f"HLS流解析失败: {str(e)}")
            return {
                "success": False,
                "error": f"HLS流解析失败: {str(e)}"
            }

    async def download_hls_and_merge(self, youtube_url: str, output_path: str, quality: str = "720p") -> Dict[str, Any]:
        """下载HLS流并使用FFmpeg合成完整视频"""
        try:
            # 第一步：获取流信息
            stream_result = await self.get_hls_streams_and_merge(youtube_url, quality)
            
            if not stream_result["success"]:
                return stream_result
            
            stream_data = stream_result["data"]
            video_url = stream_data["video_stream_url"]
            audio_url = stream_data.get("audio_stream_url")
            
            if not video_url:
                return {
                    "success": False,
                    "error": "未能获取视频流URL"
                }
            
            logger.info(f"🔽 开始下载HLS流并合成...")
            logger.info(f"📺 视频流: {video_url[:100]}...")
            if audio_url:
                logger.info(f"🎵 音频流: {audio_url[:100]}...")
            
            import tempfile
            import os
            import subprocess
            from utils.ffmpeg_helper import get_ffmpeg_path
            
            # 创建临时文件
            temp_dir = tempfile.mkdtemp(prefix="youtube_hls_")
            video_temp = os.path.join(temp_dir, "video.mp4")
            audio_temp = os.path.join(temp_dir, "audio.mp4") if audio_url else None
            
            try:
                # 获取代理配置
                proxy_config = self._get_proxy_config()
                proxies = None
                if proxy_config and 'proxy' in proxy_config:
                    proxies = {
                        'http': proxy_config['proxy'],
                        'https': proxy_config['proxy']
                    }
                
                # 第二步：下载视频流
                logger.info("📺 正在下载视频流...")
                video_success = await self._download_stream(video_url, video_temp, proxies, "视频")
                
                if not video_success:
                    return {
                        "success": False,
                        "error": "视频流下载失败"
                    }
                
                # 第三步：下载音频流（如果存在）
                audio_success = True
                if audio_url:
                    logger.info("🎵 正在下载音频流...")
                    audio_success = await self._download_stream(audio_url, audio_temp, proxies, "音频")
                
                if not audio_success:
                    logger.warning("⚠️ 音频流下载失败，将使用仅视频")
                    audio_temp = None
                
                # 第四步：使用FFmpeg合成
                logger.info("🔧 正在使用FFmpeg合成最终视频...")
                merge_success = await self._merge_streams_with_ffmpeg(
                    video_temp, 
                    audio_temp, 
                    output_path, 
                    stream_data
                )
                
                if not merge_success:
                    return {
                        "success": False,
                        "error": "FFmpeg合成失败"
                    }
                
                # 验证输出文件
                if not os.path.exists(output_path) or os.path.getsize(output_path) == 0:
                    return {
                        "success": False,
                        "error": "合成的视频文件无效或为空"
                    }
                
                file_size = os.path.getsize(output_path)
                
                result = {
                    "success": True,
                    "file_path": output_path,
                    "file_size": file_size,
                    "file_size_mb": round(file_size / 1024 / 1024, 2),
                    "stream_info": stream_data,
                    "method": "HLS流下载 + FFmpeg合成",
                    "has_audio": bool(audio_temp),
                    "temp_dir_cleaned": False  # 先保留临时文件用于调试
                }
                
                logger.info(f"✅ HLS下载和合成完成!")
                logger.info(f"📁 输出文件: {output_path}")
                logger.info(f"📦 文件大小: {result['file_size_mb']}MB")
                logger.info(f"🎬 分辨率: {stream_data['resolution']}")
                
                return result
                
            finally:
                # 清理临时文件
                try:
                    import shutil
                    if os.path.exists(temp_dir):
                        shutil.rmtree(temp_dir)
                        logger.info("🧹 临时文件已清理")
                except Exception as e:
                    logger.warning(f"临时文件清理失败: {str(e)}")
                
        except Exception as e:
            logger.error(f"HLS下载和合成失败: {str(e)}")
            return {
                "success": False,
                "error": f"下载失败: {str(e)}"
            }

    async def _download_stream(self, stream_url: str, output_path: str, proxies: dict, stream_type: str) -> bool:
        """下载单个流到文件"""
        try:
            import requests
            from tqdm import tqdm
            
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
                'Accept': '*/*',
                'Accept-Encoding': 'gzip, deflate',
                'Connection': 'keep-alive',
            }
            
            # 配置SSL和连接参数
            session = requests.Session()
            session.headers.update(headers)
            if proxies:
                session.proxies.update(proxies)
            
            # 禁用SSL验证（仅用于测试代理连接）
            session.verify = False
            
            # 禁用SSL警告
            import urllib3
            urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
            
            response = session.get(stream_url, stream=True, timeout=30)
            response.raise_for_status()
            
            total_size = int(response.headers.get('content-length', 0))
            
            with open(output_path, 'wb') as f:
                if total_size == 0:
                    # 如果无法获取总大小，直接下载
                    for chunk in response.iter_content(chunk_size=8192):
                        if chunk:
                            f.write(chunk)
                else:
                    # 显示进度条
                    downloaded = 0
                    for chunk in response.iter_content(chunk_size=8192):
                        if chunk:
                            f.write(chunk)
                            downloaded += len(chunk)
                            progress = (downloaded / total_size) * 100
                            if downloaded % (1024 * 1024) == 0:  # 每MB显示一次进度
                                logger.info(f"📥 {stream_type}下载进度: {progress:.1f}% ({downloaded//1024//1024}MB/{total_size//1024//1024}MB)")
            
            file_size = os.path.getsize(output_path)
            logger.info(f"✅ {stream_type}流下载完成: {file_size//1024//1024}MB")
            return file_size > 0
            
        except Exception as e:
            logger.error(f"{stream_type}流下载失败: {str(e)}")
            return False

    async def _merge_streams_with_ffmpeg(self, video_path: str, audio_path: str, output_path: str, stream_info: dict) -> bool:
        """使用FFmpeg合成音视频流"""
        try:
            import subprocess
            from utils.ffmpeg_helper import get_ffmpeg_path
            
            ffmpeg_path = get_ffmpeg_path()
            if not ffmpeg_path:
                logger.error("FFmpeg未找到，无法合成视频")
                return False
            
            # 构建FFmpeg命令
            cmd = [ffmpeg_path]
            
            # 添加输入文件
            cmd.extend(['-i', video_path])
            if audio_path and os.path.exists(audio_path):
                cmd.extend(['-i', audio_path])
            
            # 编码参数
            if audio_path and os.path.exists(audio_path):
                # 有音频的情况
                cmd.extend([
                    '-c:v', 'copy',  # 复制视频流（避免重新编码）
                    '-c:a', 'aac',   # 音频编码为AAC
                    '-b:a', '128k',  # 音频码率
                ])
            else:
                # 仅视频的情况
                cmd.extend([
                    '-c:v', 'copy',  # 复制视频流
                    '-an'            # 无音频
                ])
            
            # 输出参数
            cmd.extend([
                '-movflags', '+faststart',  # 优化在线播放
                '-y',                       # 覆盖输出文件
                output_path
            ])
            
            logger.info(f"🔧 FFmpeg命令: {' '.join(cmd)}")
            
            # 执行FFmpeg
            process = subprocess.run(
                cmd,
                capture_output=True,
                text=True,
                timeout=300  # 5分钟超时
            )
            
            if process.returncode == 0:
                logger.info("✅ FFmpeg合成成功")
                return True
            else:
                logger.error(f"FFmpeg合成失败:")
                logger.error(f"stdout: {process.stdout}")
                logger.error(f"stderr: {process.stderr}")
                return False
                
        except subprocess.TimeoutExpired:
            logger.error("FFmpeg合成超时")
            return False
        except Exception as e:
            logger.error(f"FFmpeg合成异常: {str(e)}")
            return False